package com.bjfu.college.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjfu.college.mapper.IntentionSchemeIntentionRecordMapper;
import com.bjfu.college.pojo.IntentionSchemeIntentionRecord;
import com.bjfu.college.pojo.UniversityIntentionRecord;
import com.bjfu.college.service.IntentionSchemeIntentionRecordService;
import com.bjfu.college.vo.RiskInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
* @author 87290
* @description 针对表【intention_scheme_intention_record】的数据库操作Service实现
* @createDate 2023-07-13 17:37:39
*/
@Service
public class IntentionSchemeIntentionRecordServiceImpl extends ServiceImpl<IntentionSchemeIntentionRecordMapper, IntentionSchemeIntentionRecord>
    implements IntentionSchemeIntentionRecordService{

    @Autowired
    private IntentionSchemeIntentionRecordMapper intentionSchemeIntentionRecordMapper;

    /**
     * @Description: 在志愿方案与志愿记录中间表中添加数据,并且利用isOverLay表明是否是覆盖
     * @Author: Pzf
     * @Date:   2023/7/15 15:23
     * @Param:  [universityIntentionRecordList, schemeId, isOverLay]
     * @Return: java.util.List<java.lang.Integer> 返回插入的冲，稳，保的记录数
     */
    @Override
    @Transactional
    public RiskInfo addSchemeRecordRelation(
            List<UniversityIntentionRecord> universityIntentionRecordList,
            int schemeId,int predictScore, int scoreBias){
        // 是否添加成功
        boolean isAdd;
        // 排序计数器
        int rank = 0;
        // 分别记录冲，稳，保的记录数
        int radicalChoiceCount = 0 ,safeChoiceCount = 0 ,conservativeChoiceCount = 0;
        // 今年的参考分
        int thisYearReferenceScore;
        // 批量插入的List
        List<IntentionSchemeIntentionRecord> intentionSchemeIntentionRecords = new ArrayList<>();
        for (UniversityIntentionRecord universityIntentionRecord : universityIntentionRecordList) {
            rank++;
            IntentionSchemeIntentionRecord intentionSchemeIntentionRecord = new IntentionSchemeIntentionRecord();
            // 对每一个插入的记录进行赋值
            intentionSchemeIntentionRecord.setSchemeId(schemeId);
            intentionSchemeIntentionRecord.setIsDeleted(0);
            intentionSchemeIntentionRecord.setRanking(rank);
            intentionSchemeIntentionRecord.setRecordId(universityIntentionRecord.getId());
            thisYearReferenceScore = universityIntentionRecord.getThisYearReferenceScore();
            // 根据学生的预测分以及相应区间，给当前记录打上风险标签
            if ( thisYearReferenceScore > predictScore && thisYearReferenceScore <= predictScore + scoreBias){
                intentionSchemeIntentionRecord.setRisk("冲");
                radicalChoiceCount++;
            } else if (thisYearReferenceScore <= predictScore && thisYearReferenceScore >= predictScore - scoreBias){
                intentionSchemeIntentionRecord.setRisk("稳");
                safeChoiceCount++;
            } else if (thisYearReferenceScore < predictScore - scoreBias && thisYearReferenceScore >= predictScore - 2 * scoreBias){
                intentionSchemeIntentionRecord.setRisk("保");
                conservativeChoiceCount++;
            }
            intentionSchemeIntentionRecords.add(intentionSchemeIntentionRecord);
        }
        try {
            isAdd = this.saveBatch(intentionSchemeIntentionRecords);
            if (isAdd) {
                RiskInfo riskInfo = new RiskInfo();
                riskInfo.setSchemeId(schemeId);
                ArrayList<Integer> riskCount = new ArrayList<>();
                riskCount.add(radicalChoiceCount);riskCount.add(safeChoiceCount);riskCount.add(conservativeChoiceCount);
                riskInfo.setRiskRecordsCount(riskCount);
                return riskInfo;
            }
            else{
                throw new RuntimeException("批量插入志愿方案与志愿记录中间表数据失败");
            }
        } catch (Exception e) {
            throw new RuntimeException("批量插入志愿方案与志愿记录中间表数据失败:" + e.toString());
        }
    }

    /**
     * @Description: 更新中间表记录的rank值
     * @Author: Pzf
     * @Date:   2023/7/16 16:22
     * @Param:  [id, newRank]
     * @Return: boolean
     */
    @Override
    @Transactional
    public boolean updateRecordsRankById(int schemeId, int recordId, int newRank){
        // 首先将当前记录与排在newRank（包括）之间的记录的ranking字段自增1
        UpdateWrapper<IntentionSchemeIntentionRecord> oldUpdateWrapper = new UpdateWrapper<>();
        // 通过id,获取到当前要调整位次的记录
        QueryWrapper<IntentionSchemeIntentionRecord> intentionRecordQueryWrapper = new QueryWrapper<>();
        // 确定到某条方案的某条记录
        intentionRecordQueryWrapper.eq("scheme_id",schemeId).eq("record_id",recordId);
        // 获取记录
        IntentionSchemeIntentionRecord record = intentionSchemeIntentionRecordMapper.selectOne(intentionRecordQueryWrapper);
        oldUpdateWrapper.eq("scheme_id",record.getSchemeId());
        // 根据新位次是在当前位次之上还是之下进行不同的set处理
        if (record.getRanking() > newRank) {
            oldUpdateWrapper.between("ranking", newRank ,record.getRanking() - 1 );
            oldUpdateWrapper.setSql("ranking = ranking + 1");
        } else {
            oldUpdateWrapper.between("ranking", record.getRanking() + 1, newRank);
            oldUpdateWrapper.setSql("ranking = ranking - 1");
        }

        // 更新中间的记录的位次
        try {
            intentionSchemeIntentionRecordMapper.update(null,oldUpdateWrapper);
        } catch (Exception e) {
            throw new RuntimeException("旧志愿记录更新失败" + e.toString());
        }

        // 将当前记录的ranking值改成newRank
        record.setRanking(newRank);
        try {
            int update = intentionSchemeIntentionRecordMapper.updateById(record);
            if (update == 0){
                throw new RuntimeException("新志愿记录更新失败");
            }
        } catch (Exception e) {
            throw new RuntimeException("新志愿记录更新失败" + e.toString());
        }
        return true;
    }


    /**
     * @Description: 根据方案id删除中间表的记录
     * @Author: Pzf
     * @Date:   2023/7/16 17:57
     * @Param:  [schemeId]
     * @Return: boolean
     */
    @Override
    @Transactional
    public int deleteSchemeRecordRelation(int schemeId){
        // 受影响的行数
        int result;
        UpdateWrapper<IntentionSchemeIntentionRecord> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("scheme_id",schemeId);
        try {
            result = intentionSchemeIntentionRecordMapper.delete(updateWrapper);
        } catch (Exception e) {
            throw new RuntimeException("删除中间表方案记录失败");
        }
        return result;
    }


    /**
     * @Description: IntentionSchemeIntentionRecord的记录逻辑删除
     * @Author: Pzf
     * @Date:   2023/7/18 0:40
     * @Param:  [schemeId, recordId]
     * @Return: int
     */
    @Override
    @Transactional
    public int logicDelete(int schemeId, int recordId){
        int updateRow;
        UpdateWrapper<IntentionSchemeIntentionRecord> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("scheme_id",schemeId).eq("record_id",recordId);
        updateWrapper.set("is_deleted",1);
        try {
            updateRow = intentionSchemeIntentionRecordMapper.update(null, updateWrapper);
        } catch (Exception e) {
            throw new RuntimeException("逻辑删除失败");
        }
        return updateRow;
    }

    /**
     * @Description: 通过志愿记录的记录Id表，对中间表中相应的逻辑删除字段进行恢复
     * @Author: Pzf
     * @Date:   2023/7/16 21:04
     * @Param:  [ids]
     * @Return: int
     */
    @Override
    @Transactional
    public int recoverLogicDeleted(int schemeId,List<Integer> ids){
        // 恢复的记录数
        int update;
        // 利用中间表构造器
        UpdateWrapper<IntentionSchemeIntentionRecord> midTbUpdateWrapper = new UpdateWrapper<>();
        midTbUpdateWrapper.eq("scheme_id",schemeId).in("record_id",ids).eq("is_deleted",1);
        midTbUpdateWrapper.set("is_deleted",0);
        try {
            update = intentionSchemeIntentionRecordMapper.update(null, midTbUpdateWrapper);
        } catch (Exception e) {
            throw new RuntimeException("逻辑删除恢复失败");
        }
        return update;
    }

    /**
     * @Description: 根据Id返回每个方案的冲稳保记录数
     * @Author: Pzf
     * @Date:   2023/7/20 21:40
     * @Param:  [schemeId]
     * @Return: java.util.List<java.lang.Integer>
     */
    @Override
    public List<Integer> queryRiskBySchemeId(int schemeId){
        QueryWrapper<IntentionSchemeIntentionRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("scheme_id",schemeId).eq("is_deleted",0).groupBy("risk");
        List<Integer> risk = intentionSchemeIntentionRecordMapper.queryRiskRecordsCount(queryWrapper);
        return risk;
    }

}




